home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / DSUTIL12 / FSPLIT / FSPLIT.PAS < prev   
Pascal/Delphi Source File  |  1993-09-20  |  17KB  |  527 lines

  1. {-----------------------------------------------------------------------}
  2. { PROJECT        NON-PROFIT HIGH QUALITY PROFESSIONAL SOFTWARE,  }
  3. {            AVAILABLE FOR ALL WORLD                }
  4. { LIBRARY        SYSTEM UTILITIES                                }
  5. { MODULE        FILE_SPLIT                                    }
  6. { FILE NAME        FSPLIT.PAS                    }
  7. { PURPOSE               SPLITES BINARY FILE TO TWO PARTIAL FILES     }
  8. { VERSION        1.20                        }
  9. { DATE            20-Sep-93                    }
  10. { DESIGN        Dmitry Stefankov                }
  11. { IMPLEMENTATION    Dmitry Stefankov                 }
  12. { COMPANY        Freelance Software Engineer            }
  13. { ADDRESS        Isakowskogo str, 4-2-30                }
  14. {            Moscow, 123181                    }
  15. {            USSR                        }
  16. {            Tel. 007 (095) 944-6304                }
  17. { COPYRIGHT NOTICE    Copyright (C) 1987-1993, Dmitry Stefankov    }
  18. { RESTRICTED RIGHTS    AVAILABLE ONLY FOR FREE DISTRIBUTION,           }
  19. {            NOT FOR COMMERCIAL PURPOSE            }
  20. { COMPUTER        IBM PC or compatible                }
  21. { OPERATING SYSTEM    MS/PC-DOS Version 3.30 or higher        }
  22. { COMPILER        Turbo Pascal Version 6.0            }
  23. {                       (Borland International Inc.)  or compatible     }
  24. { ASSEMBLY LANGUAGE    Microsoft MASM 5.10 or compatible               }
  25. { LINKER        Turbo Pascal internal                           }
  26. { ARGUMENTS             <infile>    -   input binary file        }
  27. {            <evenfile>  -   output filename (even bytes)    }
  28. {            <oddfile>   -   output filename (odd bytes)     }
  29. {                       <evencount> -   # of bytes to put in even part  }
  30. {                       <oddcount>  -   # of bytes to put in odf part   }
  31. { RETURN        See error return codes definitions        }
  32. { REQUIRES        Source Code Files                               }
  33. {                       NONE                                            }
  34. {                       External Object Files                           }
  35. {                       NONE                                            }
  36. {            Maintence Project Files                }
  37. {            NONE                        }
  38. { NATURAL LANGUAGE      English Language                                }
  39. { SPECIAL        None                        }
  40. { DESCRIPTION        1.Read   input  stream (# of bytes)             }
  41. {                       2.Format output stream (evencount of bytes put  }
  42. {                         to even stream, oddcount - to odd stream)     }
  43. {                       3.Write output streams (2 streams)        }
  44. { REVISION HISTORY    Dima Stefankov (DS)                }
  45. {               1.00  23-Mar-93  DS  initilal release        }
  46. {            1.01  30-Mar-93  DS  updated messages output    }
  47. {                       1.02  19-May-93  DS  some style updates         }
  48. {                       1.10  16-Aug-93  DS  overwritten the part of r/w}
  49. {                                            in/out streams, added more }
  50. {                                            parameters to files split  }
  51. {            1.20  20-Sep-93  DS  some style updates        }
  52. {-----------------------------------------------------------------------}
  53.  
  54.  
  55. {*======================= PROGRAM HEADER PART ==========================*}
  56.  
  57. PROGRAM SpliteBinaryFile;
  58.  
  59.  
  60. {*** other modules ***}
  61. {*USES;*}
  62.  
  63.  
  64. {** switches for compilation **}
  65. {$S-}        {*  stack checking   *}
  66. {$R-}           {*  range checking   *}
  67.  
  68.  
  69. {* generate version for debugging *}
  70. {***$DEFINE  DebugVersion}
  71.  
  72.  
  73. {*========================== CONSTANTS PART ============================*}
  74.  
  75. CONST
  76.      asPurpose                  =       'FILE SPLIT UTILITY';
  77.      asVersion                  =       '1.20';
  78.      asAuthor                   =       'Dima Stefankov';
  79.      asCopyright                =       'Copyright (c) 1987, 1993';
  80.      asProgram                  =       'FSplit';
  81.      asProgramU                 =       'FSPLIT';
  82.      asProgramPrompt            =       asProgram+': ';
  83.  
  84.      { exit codes }
  85.        errTerminateOK           =     0;
  86.        errOnLineHelp        =     1;
  87.        errSourceNotFound        =     2;
  88.        errDestDontWriteEven     =     3;
  89.        errDestDontWriteOdd      =     4;
  90.        errBadEvenCount          =     5;
  91.        errBadOddCount           =     6;
  92.  
  93.      { defaults to byte count }
  94.        aEvenCountDef         =        1;
  95.        aOddCountDef          =        1;
  96.        aEvenCountMax         =        4096;
  97.        aOddCountMax          =        4096;
  98.  
  99.      { allocating memory heaps sizes }
  100.        aMaxOutBufSize         =       aEvenCountMax;
  101.        aMaxInBufSize        =         aMaxOutBufSize * 2;
  102.  
  103.      { miscellaneous equates }
  104.        achNULL               =        #0;
  105.        achYes                =        'Y';
  106.        achHexPrefix          =        '$';
  107.        aHexRadix             =        16;
  108.  
  109.  
  110. {*====================== TYPED CONSTANTS PART ==========================*}
  111.  
  112. CONST
  113.   setHexChars  :    SET OF System.Char  =  ['0'..'9','A'..'F','a'..'f'];
  114.  
  115.   gdwEvenOutBufOfs      :       System.Word          =       0;
  116.   gdwOddOutBufOfs       :       System.Word          =       0;
  117.   gdwEvenByteCount      :       System.Word          =       aEvenCountDef;
  118.   gdwOddByteCount       :       System.Word          =       aOddCountDef;
  119.   gdwEvenIndex          :       System.Word          =       aEvenCountDef;
  120.   gdwOddIndex           :       System.Word          =       0;
  121.   gdwInActualCount      :       System.Word          =       0;
  122.   gdwInBufTotalCount    :       System.Word          =       0;
  123.   agbReadEvenPart       :       System.Boolean       =       System.True;
  124.  
  125.  
  126. {*=========================== VARIABLES PART ===========================*}
  127.  
  128. VAR
  129.   gfOutStreamEven, gfOutStreamOdd, gfInStream :  FILE;
  130.   gsOutNameEven,   gsOutNameOdd,   gsInName   :  STRING;
  131.  
  132.   glpInBuf,
  133.   glpEvenOutBuf,
  134.   glpOddOutBuf                               :  System.Pointer;
  135.   gliInBytesCount                 :  System.Longint;
  136.   gdwCmdCount                                :  System.Word;
  137.   giErrorCode                                :  System.Integer;
  138.   gsTempInput                                :  STRING;
  139.  
  140.  
  141. {*=========================== FORWARD REFERENCES =======================*}
  142.  
  143. PROCEDURE    _ProgramOutputMessage(sMessage : STRING); FORWARD;
  144.  
  145.  
  146. {*=========================== FUNCTIONAL PART ==========================*}
  147.  
  148. FUNCTION  _fnbFileExist(VAR fStruc : FILE; sFileName : STRING) : System.Boolean;
  149. {* Check that file exits. *}
  150. VAR
  151.   bResult  :  System.Boolean;
  152.  
  153. BEGIN
  154.   {** try to open the file **}
  155.   System.Assign(fStruc,sFileName);
  156.   {$I-}
  157.   System.Reset(fStruc);
  158.   {$I+}
  159.  
  160.   {** copy the result of last I/O operation **}
  161.   bResult := (System.IOResult = 0);
  162.  
  163.   IF (bResult)
  164.     THEN  System.Close(fStruc);
  165.   {if-then}
  166.  
  167.   _fnbFileExist := bResult;
  168. END; { _fnbFileExist }
  169.  
  170.  
  171. FUNCTION   _fnchGetFirstChar(sInput : STRING) : System.Char;
  172. {* Returns a first char from string. *}
  173. VAR
  174.   chTemp  :  System.Char;
  175.  
  176. BEGIN
  177.    IF (System.Length(sInput) <> 0)
  178.      THEN  chTemp := sInput[1]
  179.      ELSE  chTemp := achNULL;
  180.    {if-then-else}
  181.   _fnchGetFirstChar := chTemp;
  182. END;
  183. { _fnchGetFirstChar }
  184.  
  185.  
  186. FUNCTION  _fndbHexCharToBin(chIn: System.Char) : System.Byte; assembler;
  187. {* Converts the hexadecimal char to binary number. *}
  188. asm
  189.         mov   al,chIn        { AL = chIn }
  190.         sub   al,'0'         { AL <- AL - '0' }
  191.  
  192.         cmp   al,9           { test for digit 0-9 }
  193.         jbe   @Done
  194.  
  195.         and   al,11011111b   { make uppercase }
  196.         sub   al,'A'-'9'-1   { AL = 'A'..'F' }
  197.  
  198.       @Done:
  199.                              { AL = function result }
  200. END;
  201.     {asm-end}
  202. { _fndbHexCharToBin }
  203.  
  204.  
  205. FUNCTION  _fnliHexStrToBin(sHexInput : STRING; VAR iErrCode : System.Integer) : System.Longint;
  206. {* Converts hexadecimal string to decimal number. *}
  207. VAR
  208.   ddNumber               :       System.Longint;
  209.   dbStrIndex, dbStrLen   :       System.Byte;
  210.  
  211. BEGIN
  212.   iErrCode   := 0;
  213.   ddNumber   := 0;
  214.   dbStrIndex := 1;
  215.   dbStrLen := System.Length(sHexInput);
  216.  
  217.   WHILE (iErrCode = 0) and (dbStrLen > 0) DO
  218.   BEGIN
  219.     IF  (sHexInput[dbStrIndex] IN setHexChars)
  220.     THEN  BEGIN
  221.                ddNumber := ddNumber * aHexRadix +
  222.                            _fndbHexCharToBin(sHexInput[dbStrIndex]);
  223.                System.Inc(dbStrIndex);
  224.                System.Dec(dbStrLen);
  225.           END
  226.     ELSE
  227.         iErrCode  := -1;
  228.     {if-then-else}
  229.   END;
  230.   {while-do}
  231.  
  232.   _fnliHexStrToBin := ddNumber;
  233. END;  { _fnliHexStrToBin }
  234.  
  235.  
  236. FUNCTION  _fnddGetNum(sInput : STRING;VAR iErrorCode : System.Integer)  :  System.Longint;
  237. {* Reads a numeric string. *}
  238. VAR
  239.   ddTemp      :   System.Longint;
  240.  
  241. BEGIN
  242.   IF  (sInput[1] <> achHexPrefix)
  243.      THEN  System.Val(sInput,ddTemp,iErrorCode)
  244.      ELSE  ddTemp := _fnliHexStrToBin(Copy(sInput,2,System.Length(sInput)-1),iErrorCode);
  245.   {if-then-else}
  246.   _fnddGetNum := ddTemp;
  247. END;
  248. { _fnddGetNum }
  249.  
  250.  
  251.  
  252. {*=========================== PROCEDURAL PART ==========================*}
  253.  
  254. PROCEDURE  _PutByteToEvenOutFile(dbNextChar : System.Byte);
  255. {* Buffered writing to output stream. *}
  256. BEGIN
  257.   IF  (gdwEvenOutBufOfs >= aMaxOutBufSize)
  258.     THEN  BEGIN
  259.          _ProgramOutputMessage('Write Output Stream (even).');
  260.          System.BlockWrite(gfOutStreamEven,
  261.                            System.Mem[System.Seg(glpEvenOutBuf^):System.Ofs(glpEvenOutBuf^)],
  262.                            aMaxOutBufSize);
  263.          gdwEvenOutBufOfs := 0;
  264.           END;
  265.   {if-then}
  266.   System.Mem[System.Seg(glpEvenOutBuf^):(System.Ofs(glpEvenOutBuf^)+gdwEvenOutBufOfs)] := dbNextChar;
  267.   System.Inc(gdwEvenOutBufOfs);
  268. END;
  269. {  _PutByteToEvenOutFile }
  270.  
  271.  
  272. PROCEDURE  _PutByteToOddOutFile(dbNextChar : System.Byte);
  273. {* Buffered writing to output stream. *}
  274. BEGIN
  275.   IF  (gdwOddOutBufOfs >= aMaxOutBufSize)
  276.     THEN  BEGIN
  277.          _ProgramOutputMessage('Write Output Stream (odd).');
  278.          System.BlockWrite(gfOutStreamOdd,
  279.                            System.Mem[System.Seg(glpOddOutBuf^):System.Ofs(glpOddOutBuf^)],
  280.                            aMaxOutBufSize);
  281.          gdwOddOutBufOfs := 0;
  282.           END;
  283.   {if-then}
  284.   System.Mem[System.Seg(glpOddOutBuf^):(System.Ofs(glpOddOutBuf^)+gdwOddOutBufOfs)] := dbNextChar;
  285.   System.Inc(gdwOddOutBufOfs);
  286. END;
  287. {  _PutByteToEvenOutFile }
  288.  
  289.  
  290. FUNCTION  _fndbReadInFile : System.Byte;
  291. {* Buffered reading from even input stream. *}
  292. BEGIN
  293. {$IFDEF  DebugVersion}
  294.   _fndbReadEvenInFile := $0;
  295. {$ELSE}
  296.   IF (gdwInActualCount = 0)
  297.     THEN  BEGIN
  298.     _ProgramOutputMessage('Read Input Stream.');
  299.     {$I-}
  300.     System.BlockRead(gfInStream,
  301.                      System.Mem[System.Seg(glpInBuf^):System.Ofs(glpInBuf^)],
  302.                      aMaxInBufSize,gdwInBufTotalCount);
  303.     gdwInActualCount := gdwInBufTotalCount;
  304.     {$I+}
  305.           END;
  306.   {if-then}
  307.    System.Dec(gdwInActualCount);
  308.   _fndbReadInFile := System.Mem[System.Seg(glpInBuf^):
  309.                                     (System.Ofs(glpInBuf^)+(gdwInBufTotalCount-(1+gdwInActualCount)))];
  310. {$ENDIF  DebugVersion}
  311. END;
  312. { _fndbReadInFile }
  313.  
  314.  
  315.  
  316. PROCEDURE    _ProgramOutputMessage(sMessage : STRING);
  317. {* Output a message with a program name as prefix. *}
  318. BEGIN
  319.   System.WriteLn(asProgramPrompt+sMessage);
  320. END;
  321. { _ProgramOutputMessage }
  322.  
  323.  
  324. PROCEDURE    _CopyrightDisplay;
  325. {* Outputs the copyright notice. *}
  326. BEGIN
  327.      System.WriteLn(asPurpose+
  328.             '  Version '+
  329.             asVersion+
  330.                     ',  '+
  331.             asCopyright
  332.             +'  '+
  333.             asAuthor);
  334. END;  { _CopyrightDisplay }
  335.  
  336.  
  337. {*============================== MAIN PART =============================*}
  338.  
  339. BEGIN
  340.  
  341.   _CopyrightDisplay;
  342.  
  343.  
  344.  {* find # of user parameters *}
  345.    gdwCmdCount := System.ParamCount;
  346.  
  347.   IF (gdwCmdCount < 3)
  348.     THEN BEGIN
  349.       _ProgramOutputMessage('on-line help');
  350.       System.WriteLn(' Usage: '+asProgramU+' infile evenfile oddfile [evencount [oddcount]]');
  351.       System.WriteLn('  infile     -  source file');
  352.       System.WriteLn('  evenfile   -  destination file (1st part)');
  353.       System.WriteLn('  oddfile    -  destination file (2nd part)');
  354.       System.WriteLn('  evencount  -  # of xfr bytes at each pass to 1st part (def=',
  355.                      aEvenCountDef,',max=',aEvenCountMax,')');
  356.       System.WriteLn('  oddcount   -  # of xfr bytes at each pass to 2nd part (def=',
  357.                      aOddCountDef,',max=',aOddCountMax,')');
  358.       System.WriteLn('  Numbers may be decimals, or hexadecimals (first symbol is ''$'' for hex.).');
  359.       System.Halt(errOnLineHelp);
  360.          END
  361.     ELSE BEGIN
  362.       gsInName      := System.ParamStr(1);
  363.       gsOutNameEven := System.ParamStr(2);
  364.       gsOutNameOdd  := System.ParamStr(3);
  365.          END;
  366.   {if-then-else}
  367.  
  368.  
  369.   {** source file exists? **}
  370.   IF  NOT(_fnbFileExist(gfInStream,gsInName)) THEN
  371.   BEGIN
  372.     System.WriteLn(asProgramPrompt+'Unable to open file '+gsInName);
  373.     System.Halt(errSourceNotFound);
  374.   END;
  375.   {if-then}
  376.  
  377.   {** destination files present? **}
  378.   IF (_fnbFileExist(gfOutStreamEven,gsOutNameEven)) THEN
  379.   BEGIN
  380.     System.Write(asProgramPrompt+'Output file '+gsOutNameEven+
  381.                  ' already exists. Overwrite? (n/y): ');
  382.     System.ReadLn(gsTempInput);
  383.     IF (System.UpCase(_fnchGetFirstChar(gsTempInput)) <> achYes)
  384.       THEN  System.Halt(errDestDontWriteEven);
  385.     {if-then}
  386.   END;
  387.   {if-then}
  388.  
  389.   IF (_fnbFileExist(gfOutStreamOdd,gsOutNameOdd)) THEN
  390.   BEGIN
  391.     System.Write(asProgramPrompt+'Output file '+gsOutNameOdd+
  392.                  ' already exists. Overwrite? (n/y): ');
  393.     System.ReadLn(gsTempInput);
  394.     IF (System.UpCase(_fnchGetFirstChar(gsTempInput)) <> achYes)
  395.       THEN  System.Halt(errDestDontWriteOdd);
  396.     {if-then}
  397.   END;
  398.   {if-then}
  399.  
  400.  
  401.   {** read the following parameter = even bytes count **}
  402.   IF (gdwCmdCount >  3)
  403.     THEN  BEGIN
  404.      gsTempInput := System.ParamStr(4);
  405.      gdwEvenByteCount := _fnddGetNum(gsTempInput,giErrorCode);
  406.  
  407.      IF ((giErrorCode <> 0) OR
  408.          (aEvenCountDef > gdwEvenByteCount) OR
  409.          (gdwEvenByteCount > aEvenCountMax))
  410.       THEN
  411.          BEGIN
  412.            System.WriteLn(asProgramPrompt+' Bad even count found.');
  413.            System.Halt(errBadEvenCount);
  414.          END;
  415.       {if-then}
  416.           END;
  417.   {if-then}
  418.  
  419.  
  420.   {** read the following parameter = odd bytes count **}
  421.   IF (gdwCmdCount >  4)
  422.     THEN  BEGIN
  423.      gsTempInput := System.ParamStr(5);
  424.      gdwOddByteCount := _fnddGetNum(gsTempInput,giErrorCode);
  425.  
  426.      IF ((giErrorCode <> 0) OR
  427.          (aOddCountDef > gdwOddByteCount) OR
  428.          (gdwOddByteCount > aOddCountMax))
  429.       THEN
  430.          BEGIN
  431.            System.WriteLn(asProgramPrompt+' Bad odd count found.');
  432.            System.Halt(errBadOddCount);
  433.          END;
  434.       {if-then}
  435.           END;
  436.   {if-then}
  437.  
  438.  
  439.  
  440.  {* do in/out streams *}
  441.     System.Assign(gfInStream,gsInName);
  442.     System.Reset(gfInStream,1);
  443.  
  444.     System.Assign(gfOutStreamEven,gsOutNameEven);
  445.     System.Rewrite(gfOutStreamEven,1);
  446.  
  447.     System.Assign(gfOutStreamOdd,gsOutNameOdd);
  448.     System.Rewrite(gfOutStreamOdd,1);
  449.  
  450.  
  451.  {* allocate a memory *}
  452.     System.GetMem(glpInBuf,aMaxInBufSize);
  453.     System.GetMem(glpEvenOutBuf,aMaxOutBufSize);
  454.     System.GetMem(glpOddOutBuf,aMaxOutBufSize);
  455.  
  456.  
  457.  {* initialize the internal variables *}
  458.     gliInBytesCount := System.FileSize(gfInStream);
  459.     gdwEvenIndex := gdwEvenByteCount;
  460.  
  461.  {* main loop *}
  462.     WHILE  (gliInBytesCount <> 0) DO
  463.     BEGIN
  464.        IF  (agbReadEvenPart)
  465.           THEN  BEGIN
  466.                  WHILE (gliInBytesCount <> 0) AND (gdwEvenIndex <> 0) DO
  467.                  BEGIN
  468.                    _PutByteToEvenOutFile(_fndbReadInFile);
  469.                     System.Dec(gdwEvenIndex);
  470.                     IF (gdwEvenIndex = 0)
  471.                       THEN  gdwOddIndex := gdwOddByteCount;
  472.                     {if-then}
  473.                    System.Dec(gliInBytesCount);
  474.                  END;
  475.                  {while-do}
  476.                  agbReadEvenPart := System.False;
  477.                 END
  478.           ELSE  BEGIN
  479.                  WHILE (gliInBytesCount <> 0) AND (gdwOddIndex <> 0) DO
  480.                  BEGIN
  481.                    _PutByteToOddOutFile(_fndbReadInFile);
  482.                     System.Dec(gdwOddIndex);
  483.                     IF (gdwOddIndex = 0)
  484.                       THEN  gdwEvenIndex := gdwEvenByteCount;
  485.                     {if-then}
  486.                    System.Dec(gliInBytesCount);
  487.                  END;
  488.                  {while-do}
  489.                  agbReadEvenPart := System.True;
  490.                 END;
  491.        {if-then-else}
  492.     END;
  493.     {while-do}
  494.  
  495.  
  496.  {* check what is present in output buffers? *}
  497.   IF (gdwEvenOutBufOfs <> 0)
  498.     THEN  BEGIN
  499.        _ProgramOutputMessage('Write last output buffer (even).');
  500.        System.BlockWrite(gfOutStreamEven,
  501.                          System.Mem[System.Seg(glpEvenOutBuf^):System.Ofs(glpEvenOutBuf^)],
  502.                          gdwEvenOutBufOfs);
  503.           END;
  504.   {if-then}
  505.  
  506.   IF (gdwOddOutBufOfs <> 0)
  507.     THEN  BEGIN
  508.        _ProgramOutputMessage('Write last output buffer (odd).');
  509.        System.BlockWrite(gfOutStreamOdd,
  510.                          System.Mem[System.Seg(glpOddOutBuf^):System.Ofs(glpOddOutBuf^)],
  511.                          gdwOddOutBufOfs);
  512.           END;
  513.   {if-then}
  514.  
  515.  
  516.   _ProgramOutputMessage('Done.');
  517.  
  518.   System.FreeMem(glpEvenOutBuf,aMaxOutBufSize);
  519.   System.FreeMem(glpOddOutBuf,aMaxOutBufSize);
  520.   System.FreeMem(glpInBuf,aMaxInBufSize);
  521.  
  522.   System.Close(gfOutStreamEven);
  523.   System.Close(gfOutStreamOdd);
  524.   System.Close(gfInStream);
  525.  
  526.   {* System.Halt(errTerminateOk); *}
  527. END.